using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using HslCommunication.BasicFramework;

namespace HslCommunication.MQTT
{
	/// <summary>
	/// Mqtt的会话
	/// </summary>
	public class MqttSession
	{
		private object objLock = new object();

		/// <summary>
		/// 远程的ip地址信息
		/// </summary>
		public IPEndPoint EndPoint
		{
			get;
			set;
		}

		/// <summary>
		/// 当前接收的客户端ID信息
		/// </summary>
		public string ClientId
		{
			get;
			set;
		}

		/// <summary>
		/// 当前客户端的激活时间
		/// </summary>
		public DateTime ActiveTime
		{
			get;
			set;
		}

		/// <summary>
		/// 获取当前的客户端的上线时间
		/// </summary>
		public DateTime OnlineTime
		{
			get;
			private set;
		}

		/// <summary>
		/// 两次活动的最小时间间隔
		/// </summary>
		public TimeSpan ActiveTimeSpan
		{
			get;
			set;
		}

		/// <summary>
		/// 当前客户端绑定的套接字对象
		/// </summary>
		internal Socket MqttSocket
		{
			get;
			set;
		}

		/// <summary>
		/// 当前客户端订阅的所有的Topic信息
		/// </summary>
		private List<string> Topics
		{
			get;
			set;
		}

		/// <summary>
		/// 当前的用户名
		/// </summary>
		public string UserName
		{
			get;
			set;
		}

		/// <summary>
		/// 当前的协议信息，一般为MQTT，如果是同步客户端那么是HUSL
		/// </summary>
		public string Protocol
		{
			get;
			private set;
		}

		/// <summary>
		/// 实例化一个默认的对象
		/// </summary>
		/// <param name="endPoint">远程客户端的IP地址</param>
		/// <param name="protocol">协议信息</param>
		public MqttSession(IPEndPoint endPoint, string protocol)
		{
			Topics = new List<string>();
			ActiveTime = DateTime.Now;
			OnlineTime = DateTime.Now;
			ActiveTimeSpan = TimeSpan.FromSeconds(1000000.0);
			EndPoint = endPoint;
			Protocol = protocol;
		}

		/// <summary>
		/// 检查当前的连接对象是否在
		/// </summary>
		/// <param name="topic">主题信息</param>
		/// <returns>是否包含的结果信息</returns>
		public bool IsClientSubscribe(string topic)
		{
			bool result = false;
			lock (objLock)
			{
				result = Topics.Contains(topic);
			}
			return result;
		}

		/// <summary>
		/// 当前的会话信息新增一个订阅的信息
		/// </summary>
		/// <param name="topic">主题的信息</param>
		public void AddSubscribe(string topic)
		{
			lock (objLock)
			{
				if (!Topics.Contains(topic))
				{
					Topics.Add(topic);
				}
			}
		}

		/// <summary>
		/// 当前的会话信息新增一个订阅的信息
		/// </summary>
		/// <param name="topics">主题的信息</param>
		public void AddSubscribe(string[] topics)
		{
			if (topics == null)
			{
				return;
			}
			lock (objLock)
			{
				for (int i = 0; i < topics.Length; i++)
				{
					if (!Topics.Contains(topics[i]))
					{
						Topics.Add(topics[i]);
					}
				}
			}
		}

		/// <summary>
		/// 移除会话信息的一个订阅的主题
		/// </summary>
		/// <param name="topic">主题</param>
		public void RemoveSubscribe(string topic)
		{
			lock (objLock)
			{
				if (Topics.Contains(topic))
				{
					Topics.Remove(topic);
				}
			}
		}

		/// <summary>
		/// 移除会话信息的一个订阅的主题
		/// </summary>
		/// <param name="topics">主题</param>
		public void RemoveSubscribe(string[] topics)
		{
			if (topics == null)
			{
				return;
			}
			lock (objLock)
			{
				for (int i = 0; i < topics.Length; i++)
				{
					if (Topics.Contains(topics[i]))
					{
						Topics.Remove(topics[i]);
					}
				}
			}
		}

		/// <inheritdoc />
		public override string ToString()
		{
			return $"{Protocol}Session[{ClientId}][{EndPoint}][{SoftBasic.GetTimeSpanDescription(DateTime.Now - OnlineTime)}]";
		}
	}
}
